{
======================================================================
Project  : Firebird Control Center
Unit     : uSingleInst.pas
Purpose  : Allow only one instance of this application
Author   : Achim Kalwa <delphi@achim-kalwa.de>
Compiler : Borland Delphi 5.01
----------------------------------------------------------------------
History:
2004-02-25, Kalwa:
- Added "SwitchToThisWindow" API Call.
- "-exit" command line param sends WM_EXIT_FBCC message to main
  application, causing it to quit nicely. This will be used by
  uninstaller to shut down fbcc.
======================================================================
}
{$I fbcc.inc}
unit uSingleInst;

interface

uses
  Windows;

var
  WM_RESTORE_FROM_TRAY : Cardinal = 0;
  WM_EXIT_FBCC         : Cardinal = 0;

procedure Check(sApplication, sMutex : String);
procedure SwitchToThisWindow(aWnd: THandle; fAltTab: bool); stdcall;

implementation

uses
  Forms,
  SysUtils;

var
  Mutex : THandle;
  h     : HWnd;

procedure SwitchToThisWindow; external user32 Name 'SwitchToThisWindow';

procedure Check(sApplication, sMutex : String);
begin
  // is this application already in memory?
  Mutex := CreateMutex(nil, True, PChar(sMutex));
  if GetlastError = ERROR_ALREADY_EXISTS then begin
    // yes - find the window handle
    h := 0;
    repeat
      h := FindWindowEx(0, h, 'TApplication', PChar(sApplication))
    until h <> Application.Handle;

    if h <> 0 then begin
      if Pos('-exit', LowerCase(ParamStr(1))) > 0 then
      begin
        windows.PostMessage(h, WM_EXIT_FBCC, 0, 0);
      end
      else begin
(*
        // switch to this window
        windows.ShowWindowAsync(h, SW_SHOWNORMAL);
        windows.SetForegroundWindow(h);
*)

        // post a "RestoreFromTray" message
        windows.PostMessage(h, WM_RESTORE_FROM_TRAY, 0, 0);
        Application.ProcessMessages;

        // switch to this window
        SwitchToThisWindow(h, False);
      end;
    end;
    Halt; // we have to terminate ourself!
  end;
end; { check }

Initialization
  Mutex := 0;
  // register a unique message ID
  WM_RESTORE_FROM_TRAY := RegisterWindowMessage('RestoreFromTray');
  WM_EXIT_FBCC         := RegisterWindowMessage('ExitFBCC');

Finalization
  ReleaseMutex(Mutex);
end.
